package com.xbongbong.esign.comm;

import com.alibaba.fastjson.JSONObject;
import com.xbongbong.esign.constant.ConfigConstant;
import com.xbongbong.esign.enums.RequestType;
import com.xbongbong.esign.exception.DefineException;
import com.xbongbong.paas.redis.PaasRedisHelper;
import com.xbongbong.paas.redis.RedisPrefixConstant;
import com.xbongbong.paas.redis.RedisTimeConstant;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * @description Http 请求 辅助类
 * @author 宫清
 * @date 2019年7月19日 下午2:21:14
 * @since JDK1.7
 */
@Component
public class HttpHelper {

	@Resource
	private PaasRedisHelper paasRedisHelper;
	/**
	 * 不允许外部创建实例
	 */
	private HttpHelper() {

	}

	// ------------------------------公有方法start--------------------------------------------

	/**
	 * @description 发送常规HTTP 请求
	 *
	 * @param reqType 请求方式
	 * @param url 请求路径
	 * @param paramStr 请求参数
	 * @return
	 * @throws DefineException
	 * @date 2019年7月19日 下午2:27:59
	 * @author 宫清
	 */
	public JSONObject doCommHttp(RequestType reqType, String url, String paramStr) throws DefineException {
		return HttpCfgHelper.sendHttp(reqType, url, buildCommHeader(), paramStr);
	}
	/**
	 * @description 发送tokenHTTP 请求
	 *
	 * @param reqType 请求方式
	 * @param url 请求路径
	 * @param paramStr 请求参数
	 * @return
	 * @throws DefineException
	 * @date 2019年7月19日 下午2:27:59
	 * @author 宫清
	 */
	public JSONObject doTokenHttp(RequestType reqType, String url, String paramStr) throws DefineException {
		return HttpCfgHelper.sendHttp(reqType, url, buildTokenHeader(), paramStr);
	}

	/**
	 * @description 发送文件流上传 HTTP 请求
	 *
	 * @param reqType 请求方式
	 * @param url 请求路径
	 * @param param 请求参数
	 * @param contentMd5 文件contentMd5
	 * @param contentType 文件MIME类型
	 * @return
	 * @throws DefineException
	 * @author 宫清
	 * @date 2019年7月20日 下午8:21:28
	 */
	public JSONObject doUploadHttp(RequestType reqType, String url, byte[] param, String contentMd5,
			String contentType) throws DefineException {
		return HttpCfgHelper.sendHttp(reqType, url, buildUploadHeader(contentMd5, contentType), param);
	}

	// ------------------------------公有方法end----------------------------------------------

	// ------------------------------私有方法start--------------------------------------------

	/**
	 * @description 创建常规请求头
	 * @return
	 * @date 2019年7月19日 下午2:36:51
	 * @author 宫清
	 */
	private Map<String, String> buildCommHeader() throws DefineException {
		Map<String, String> header = new HashMap();
		header.put("X-Tsign-Open-App-Id", ConfigConstant.PROJECT_ID);
		header.put("X-Tsign-Open-Token", getOpenToken());
		header.put("Content-Type", "application/json");
		return header;
	}

	/**
	 * @description 创建token请求头
	 * @return
	 * @date 2019年7月19日 下午2:36:51
	 * @author 宫清
	 */
	private Map<String, String> buildTokenHeader() throws DefineException {
		Map<String, String> header = new HashMap();
		header.put("X-Tsign-Open-App-Id", ConfigConstant.PROJECT_ID);
		header.put("X-Tsign-Open-Token", null);
		header.put("Content-Type", "application/json");
		return header;
	}

	/**
	 * @description 创建文件流上传 请求头
	 *
	 * @param contentMd5
	 * @param contentType
	 * @return
	 * @author 宫清
	 * @date 2019年7月20日 下午8:13:15
	 */
	private Map<String, String> buildUploadHeader(String contentMd5, String contentType) {
		Map<String, String> header = new HashMap();
		header.put("Content-MD5", contentMd5);
		header.put("Content-Type", contentType);
		return header;
	}

	// ------------------------------私有方法end----------------------------------------------

	public String getOpenToken() throws DefineException {
		//从缓存获取
		String openToken = paasRedisHelper.getValue(RedisPrefixConstant.OPEN_TOKEN, "esign");
		if (Objects.isNull(openToken)) {
			JSONObject tokenJson = getTokenData();

			openToken = tokenJson.getString("token");
//			String refreshToken = tokenJson.getString("refreshToken");

			//e签宝的tokenId有效时间2小时，这边设置为1小时
			paasRedisHelper.setValue(RedisPrefixConstant.OPEN_TOKEN, "esign", openToken, RedisTimeConstant.TINY_DURATION);
//			paasRedisHelper.setValue(RedisPrefixConstant.OPEN_TOKEN, "esign", openToken, RedisTimeConstant.HOUR_DURATION);
		}
		return openToken;
	}

	/**
	 * @description 获取token
	 *
	 *              实际使用中，可获取token后，放在redis缓存中，如果是非分布式架构，也可使用guava的LoadingCache或者自己构建本地缓存来存储该token，
	 *              缓存存储时，需要注意缓存失效截止时间expiresIn
	 *
	 * @date 2019年7月19日 上午11:55:57
	 * @author 宫清
	 * @throws DefineException
	 */
	public JSONObject getTokenData() throws DefineException {
		JSONObject json = doTokenHttp(RequestType.GET,
				ConfigConstant.getToken_URL(ConfigConstant.PROJECT_ID, ConfigConstant.PROJECT_SECRET), null);
		return JSONHelper.castDataJson(json,JSONObject.class);

	}
}
